home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
vol_400
/
418_03
/
outfile.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-03-02
|
51KB
|
1,882 lines
/* outfile.c
* RasMol2 Molecular Graphics
* Roger Sayle, February 1994
* Version 2.3
*/
#define OUTFILE
#include "rasmol.h"
#ifdef IBMPC
#include <windows.h>
#include <malloc.h>
#endif
#ifndef sun386
#include <stdlib.h>
#endif
#include <stdio.h>
#include <ctype.h>
#include <math.h>
#include "outfile.h"
#include "molecule.h"
#include "command.h"
#include "transfor.h"
#include "render.h"
#include "graphics.h"
#include "pixutils.h"
#ifdef EIGHTBIT
#define RComp(x) (RLut[LutInv[x]])
#define GComp(x) (GLut[LutInv[x]])
#define BComp(x) (BLut[LutInv[x]])
#else
#define RComp(x) (((x)>>16)&0xff)
#define GComp(x) (((x)>>8)&0xff)
#define BComp(x) ((x)&0xff)
#endif
/* Sun rasterfile.h macro defns */
#define RAS_MAGIC 0x59a66a95
#define RAS_RLE 0x80
#define RT_STANDARD 1
#define RT_BYTE_ENCODED 2
#define RMT_NONE 0
#define RMT_EQUAL_RGB 1
/* Standard A4 size page: 8.267x11.811 inches */
/* U.S. Normal size page: 8.500x11.000 inches */
#define PAGEHIGH (11.811*72.0)
#define PAGEWIDE (8.267*72.0)
#define BORDER 0.90
/* Compression Ratio 0<x<127 */
#define EPSFCompRatio 32
#define Round(x) ((int)(x))
#define Rad2Deg (180.0/PI)
#define Deg2Rad (PI/180.0)
#define PSLine 0x00
#define PSStick 0x01
#define PSSphere 0x02
typedef void __far* PSItemPtr;
#ifdef IBMPC
static short __far *ABranch;
static short __far *DBranch;
static short __far *Hash;
static Byte __far *Node;
#else
static short ABranch[4096];
static short DBranch[4096];
static short Hash[256];
static Byte Node[4096];
#endif
typedef struct {
Byte len;
Byte ch;
} BMPPacket;
static BMPPacket BMPBuffer[10];
static int BMPCount,BMPTotal;
static int BMPPad;
static int GIFClrCode;
static int GIFEOFCode;
static Card RLEFileSize;
static int RLEEncode;
static int RLEOutput;
static int RLELength;
static int RLEPixel;
static int RLEChar;
static Byte Buffer[256];
static Byte LutInv[256];
static int LineLength;
static FILE *OutFile;
static Card BitBuffer;
static int BitBufLen;
static int PacketLen;
static int CodeSize;
static Real LineWidth;
static int VectSolid;
static int VectCol;
/* Macros for commonly used loops */
#define ForEachAtom for(chain=Database->clist;chain;chain=chain->cnext) \
for(group=chain->glist;group;group=group->gnext) \
for(aptr=group->alist;aptr;aptr=aptr->anext)
#define ForEachBond for(bptr=Database->blist;bptr;bptr=bptr->bnext)
#define ForEachBack for(chain=Database->clist;chain;chain=chain->cnext) \
for(bptr=chain->blist;bptr;bptr=bptr->bnext)
static void FatalOutputError( ptr )
char *ptr;
{
if( CommandActive ) WriteChar('\n');
WriteString("Output Error: Unable to create file `");
WriteString( ptr ); WriteString("'!\n");
CommandActive = False;
}
static void WritePPMWord( i )
int i;
{
if( i>99 )
{ fputc((i/100)+'0',OutFile); i %= 100;
fputc((i/10) +'0',OutFile); i %= 10;
} else if( i>9 )
{ fputc((i/10)+'0',OutFile); i %= 10;
}
putc(i+'0',OutFile);
}
int WritePPMFile( name, raw )
char *name; int raw;
{
register Pixel __huge *ptr;
register int i, c;
register int x,y;
#ifdef IBMPC
OutFile = fopen(name, (raw?"wb":"w") );
#else
OutFile = fopen(name,"w");
#endif
if( !OutFile )
{ FatalOutputError(name);
return( False );
}
fputc('P',OutFile); fputc((raw?'6':'3'),OutFile);
fprintf(OutFile," %d %d 255\n",XRange,YRange);
#ifdef EIGHTBIT
for( i=0; i<256; i++ )
if( ULut[i] )
LutInv[Lut[i]] = i;
#endif
#ifdef IBMPC
FBuffer = (Pixel __huge*)GlobalLock(FBufHandle);
#endif
#ifndef INVERT
ptr = FBuffer;
#endif
c = 0;
if( !raw )
{ c = 0;
for( y=YRange-1; y>=0; y-- )
{
#ifdef INVERT
ptr = FBuffer + (Long)y*XRange;
#endif
for( x=0; x<XRange; x++ )
{ i = *ptr++; c++;
WritePPMWord((int)RComp(i)); fputc(' ',OutFile);
WritePPMWord((int)GComp(i)); fputc(' ',OutFile);
WritePPMWord((int)BComp(i));
if( c==5 )
{ c=0; fputc('\n',OutFile);
} else fputc(' ',OutFile);
}
}
} else
for( y=YRange-1; y>=0; y-- )
{
#ifdef INVERT
ptr = FBuffer + (Long)y*XRange;
#endif
for( x=0; x<XRange; x++ )
{ i = *ptr++;
fputc((int)RComp(i),OutFile);
fputc((int)GComp(i),OutFile);
fputc((int)BComp(i),OutFile);
}
}
fclose(OutFile);
#ifdef IBMPC
GlobalUnlock(FBufHandle);
#endif
return( True );
}
#ifdef EIGHTBIT
static int CompactColourMap()
{
register Pixel __huge *ptr;
register Long pos, count;
register int i, cols;
for( i=0; i<256; i++ )
{ if( ULut[i] )
LutInv[Lut[i]] = i;
Buffer[i] = 0;
Node[i] = 5;
}
#ifdef IBMPC
ptr = (Pixel __huge*)GlobalLock(FBufHandle);
#else
ptr = FBuffer;
#endif
cols = 0;
count = (Long)XRange*YRange;
for( pos=0; pos<count; pos++ )
{ i = LutInv[*ptr++];
if( !Buffer[i] )
{ Node[cols++] = i;
Buffer[i] = cols;
}
}
for( i=0; i<256; i++ )
LutInv[i] = Buffer[LutInv[i]]-1;
#ifdef IBMPC
GlobalUnlock(FBufHandle);
#endif
return( cols );
}
#endif
static void WriteGIFCode( code )
int code;
{
register int max;
max = (code==GIFEOFCode)? 0 : 7;
BitBuffer |= ((Card)code<<BitBufLen);
BitBufLen += CodeSize;
while( BitBufLen > max )
{
#ifdef IBMPC
Buffer[PacketLen++]=(Byte)(BitBuffer&0xff);
#else
Buffer[PacketLen++]=BitBuffer;
#endif
BitBuffer >>= 8;
BitBufLen -= 8;
if( PacketLen==255 )
{ fputc(0xff,OutFile);
fwrite((char*)Buffer,1,255,OutFile);
PacketLen = 0;
}
}
}
int WriteGIFFile( name )
char *name;
{
register int i,j,cols;
register int pref,next,last;
register int isize, ilast;
register Pixel __huge *ptr;
register short __far *prev;
register int x,y,init;
#ifdef EIGHTBIT
cols = CompactColourMap();
if( cols<2 ) return( False );
for( isize=0; isize<8; isize++ )
if( (1<<isize)>=cols ) break;
cols = 1<<isize;
#ifdef IBMPC
OutFile = fopen(name,"wb");
#else
OutFile = fopen(name,"w");
#endif
if( !OutFile )
{ FatalOutputError(name);
return( False );
}
fwrite("GIF87a",1,6,OutFile);
fputc(XRange&0xff,OutFile); fputc((XRange>>8)&0xff,OutFile);
fputc(YRange&0xff,OutFile); fputc((YRange>>8)&0xff,OutFile);
fputc(0xf0|(isize-1),OutFile);
fputc(0x00,OutFile);
fputc(0x00,OutFile);
for( j=0; j<cols; j++ )
{ i = Node[j];
fputc((int)RLut[i],OutFile);
fputc((int)GLut[i],OutFile);
fputc((int)BLut[i],OutFile);
}
fputc(',',OutFile);
fputc(0x00,OutFile); fputc(0x00,OutFile);
fputc(0x00,OutFile); fputc(0x00,OutFile);
fputc(XRange&0xff,OutFile); fputc((XRange>>8)&0xff,OutFile);
fputc(YRange&0xff,OutFile); fputc((YRange>>8)&0xff,OutFile);
fputc(0x00,OutFile); fputc(isize,OutFile);
PacketLen=0;
BitBuffer=0;
BitBufLen=0;
GIFClrCode = (1<<isize);
GIFEOFCode = GIFClrCode+1;
ilast = (GIFClrCode<<1)-GIFEOFCode;
isize++;
CodeSize = isize;
last = ilast;
next = 1;
WriteGIFCode(GIFClrCode);
for( i=0; i<cols; i++ )
Hash[i]=0;
#ifdef IBMPC
FBuffer = (Pixel __huge*)GlobalLock(FBufHandle);
#endif
#ifndef INVERT
ptr = FBuffer;
#endif
/* Avoid Warnings! */
prev = (short __far*)0;
pref = 0;
ini